package com.mason.wx.controller;

import com.mason.wx.message.NewsMessage;
import com.mason.wx.message.TextMessage;
import com.mason.wx.utils.EventUtils;
import com.mason.wx.utils.HttpUtils;
import com.mason.wx.utils.ImageUtils;
import com.mason.wx.utils.XmlUtils;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 马拉圈
 * Date: 2023-10-18
 * Time: 23:03
 */
@Slf4j
@RestController
public class WxController {

    @GetMapping("/hello")
    public String hello() {
        log.info("hello");
        return "<h1>hello</h1>";
    }

    @GetMapping("/")
    public String check(@RequestParam("signature") String signature,
                        @RequestParam("timestamp") String timestamp,
                        @RequestParam("nonce") String nonce,
                        @RequestParam("echostr") String echostr) {
        if(!StringUtils.hasLength(signature) || !StringUtils.hasLength(timestamp)
                || !StringUtils.hasLength(nonce) || !StringUtils.hasLength(echostr)) {
            return "";
        }
        // 1) 将token 、 timestamp 、 nonce 三个参数进行字典序排序
        String token = "maras103";
        String[] list = {token, timestamp, nonce};
        Arrays.sort(list);
        // 2) 将三个字符串以此顺序进行拼接
        StringBuilder builder = new StringBuilder();
        for(String s : list) {
            builder.append(s);
        }
        // 2.1) 加密
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("sha1");
            byte[] digest = messageDigest.digest(builder.toString().getBytes(StandardCharsets.UTF_8));
            // 2.2) 将加密后的byte数组转换为signature一样的格式（每个字节都转换为十六进制进行拼接）
            builder = new StringBuilder();
            for(byte b : digest) {
                // builder.append(Integer.toHexString(b));不能这么弄因为这样弄b如果是负，那么就凉凉
                // 这样写保证两位十六进制都存在并且正确
                builder.append(Integer.toHexString((b >> 4) & 15));//前四个字节转换为十六进制
                builder.append(Integer.toHexString(b & 15));//后四个字节转换为十六进制
            }
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        // 3) 核对请求是否来自于微信（加密解析后的字符串与signature比较）
        if(builder.toString().equals(signature)) {
            // 相同才返回回显字符串
            // 并且返回echostr代表开发者确认了这是公众号服务器发来的请求，公众号就进行配置
            return echostr;
        } else {
            // 否则返回null
            return null;
        }

    }

    @PostMapping("/")
    public String receiveMessage(HttpServletRequest request) throws IOException {
        String body = HttpUtils.getBody(request);
        Map<String, Object> map = XmlUtils.xmlToMap(body);
        System.out.println(map);
//        Map<String, String> map = XmlUtils.xmlToMap(request.getInputStream());
//        log.info(map.toString());
        // 回复消息
        String message = "";
        String MsgType = (String) map.get("MsgType");
        switch (MsgType) {
            case "event":
                message = handleEvent(map);//处理事件
                break;
            case "text":
                message = handleText(map);//处理文本
                break;
            case "image":
                message = handleImage(map);//处理图片
                break;
            default:
                System.out.println("其他消息类型");
                break;
        }

//        System.out.println(message);
        return message;
    }

    private String handleImage(Map<String, Object> map) {
        String picUrl = (String) map.get("PicUrl");
        String content = ImageUtils.getImageText(picUrl);
        map.put("Content", content);
        TextMessage textMessage = TextMessage.getReplyTextMessage(map);
        String message = XmlUtils.objectToXml(textMessage);
        return message;
    }

    private String handleText(Map<String, Object> map) {
        String message = "";
        if("图文".equals(map.get("Content"))) {
            NewsMessage newsMessage = NewsMessage.getReplyNewsMessage(map);
            message = XmlUtils.objectToXml(newsMessage);
            System.out.println(message);
        }else {
            // 1. 封装对象
            TextMessage textMessage = TextMessage.getAntonym(map);
            // 2. 序列化对象
            message = XmlUtils.objectToXml(textMessage);
        }
        return message;
    }

    private String handleEvent(Map<String, Object> map) {
        String message = "";
        // 获取event值
        String event = (String) map.get("Event");
        // 事件分支
        switch (event) {
            case "CLICK":
                message = EventUtils.handleClick(map);
                break;
            case "VIEW":
                System.out.println("view");
                break;
            case "SCAN":
                message = EventUtils.handleScan(map);
                break;
            case "subscribe":
                message = EventUtils.handleSubscribe(map);
                break;
            default:
                break;
        }
        return message;
    }


}
